﻿using System;
using System.Linq;
using System.Net;
using LinkedIn;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Threading;
using LinkedIn.Utility;
using RoketSolutions.SP2010.Infrostructure.Localization;
using RoketSolutions.SP2010.Infrostructure.UI.Controls;
using RoketSolutions.SP2010.LinkedInWebPart.Authorization;
using RoketSolutions.SP2010.LinkedInWebPart.Common;
using RoketSolutions.SP2010.LinkedInWebPart.Data;
using RoketSolutions.SP2010.LinkedInWebPart.WebParts;

namespace RoketSolutions.SP2010.LinkedInWebPart.CONTROLTEMPLATES.RoketSolutions.SP2010.LinkedInWebPart
{
    public partial class LinkedInAuthorizerUserControl : LocalizableUserControl, ILinkedInControl
    {
        private Token accessToken;
        private SPTokenManager tokenManager;
        protected LinkedInEntity entity;

        private WebOAuthAuthorization Authorization
        {
            get;
            set;
        }

        private SPTokenManager TokenManager
        {
            get
            {
                if (tokenManager == null)
                {
                    if (TokenSource != null)
                    {
                        tokenManager = new SPTokenManager(TokenSource);
                    }
                    else
                    {
                        throw new ArgumentNullException("Please specify token source");
                    }
                }
                return tokenManager;
            }
        }

        private Token AccessToken
        {
            get
            {
                return accessToken ?? (accessToken = TokenManager.GetAccessToken());
            }
        }

        public TokenSource TokenSource { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                LabelError.Visible = false;
                LiteralPleaseLogin.Text = Resources.For<Labels>(ResourceConfig).Get(item => item.PleaseLoginMessage);
                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                SPContext.Current.Web.AllowUnsafeUpdates = true;
                var accessTokenKey = AccessToken == null ? string.Empty : AccessToken.Key;
                Authorization = new WebOAuthAuthorization(TokenManager, accessTokenKey);

                if (string.IsNullOrEmpty(accessTokenKey))
                {
                    LoginOrEmptyView();
                }
                else
                {
                    loginStatusMultiView.SetActiveView(LinkedInView);
                    ShowCurrentUserInfo();
                }

                if (!IsPostBack)
                {
                    string accToken = Authorization.CompleteAuthorize();
                    if (accToken != null)
                    {
                        Response.Redirect(Request.Path);
                    }
                }
            }
            catch (ThreadAbortException) { }
            catch (LinkedInNotAuthorizedException ex)
            {
                LabelError.Text = ex.Message;
                LabelError.Visible = true;
                tokenManager.RemoveRequestToken();
                tokenManager.RemoveAccessToken();
                loginStatusMultiView.SetActiveView(LoginView);
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Epam.SharePoint.LinkedInSync", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
                throw new SPException(ex.Message);
            }
            finally
            {
                SPContext.Current.Web.AllowUnsafeUpdates = false;
            }
        }

        private void LoginOrEmptyView()
        {
            loginStatusMultiView.SetActiveView(LoginView);
        }

        protected void logInUsingLinkedInButton_Click(object sender, EventArgs e)
        {
            if (AccessToken == null)
            {
                Authorization.BeginAuthorize();
            }
        }

        protected void logOutButton_Click(object sender, EventArgs e)
        {
            var service = new LinkedInService(Authorization);
            service.InvalidateToken();
            tokenManager.RemoveAccessToken();
            loginStatusMultiView.ActiveViewIndex = 0;
        }

        private void ShowCurrentUserInfo()
        {
            try
            {
                LiteralCurrentPositions.Text = Resources.For<Labels>(ResourceConfig).Get(item => item.CurrentPositionMessage);
                LiteralConnections.Text = Resources.For<Labels>(ResourceConfig).Get(item => item.LiteralConnectionsMessage);
                LiteralEducation.Text = Resources.For<Labels>(ResourceConfig).Get(item => item.LiteralEducationMessage);
                LiteralExperience.Text = Resources.For<Labels>(ResourceConfig).Get(item => item.LiteralExperienceMessage);

                entity = new LinkedInRepository(TokenManager).GetCurrentUser();
                imgPhoto.Src = entity.ProfilePictureUrl;
                lblFirstName.Text = entity.FirstName;
                lblLastName.Text = entity.LastName;
                linkPuplicProfile.HRef = entity.PublicProfileUrl;
                lblTitle.Text = entity.Headline;
                lblConectionsCount.Text = entity.ConnectionsCount;
                lblIndustry.Text = entity.Industry;
                lblLocation.Text = entity.Location;
                if (!string.IsNullOrEmpty(entity.CurrentPositions))
                {
                    rptCurrentPositions.DataSource = entity.CurrentPositions.Trim().Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
                    rptCurrentPositions.DataBind();
                }
                if (!string.IsNullOrEmpty(entity.Education))
                {
                    rptEducation.DataSource = entity.Education.Trim().Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
                    rptEducation.DataBind();
                }
                if (!string.IsNullOrEmpty(entity.Experience))
                {
                    rptExperience.DataSource = entity.Experience.Trim().Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
                    rptExperience.DataBind();
                }
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Epam.SharePoint.LinkedInSync", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
                throw;
            }
        }
    }
}
